package ae.pcfc.etks.online.web.controller.admin.workflow.general.person.request;

/* $Id: AdminClientPersonController.java 
 * Copyright (C) 2011, TRAKHEES
 *  
 * Revision History
 *
 * Date  			Author 		    	Remarks
 * ---------------------------------------------------------------------------------
 * April 11, 2011 	Mohtisham.Salahria	Created
 *
 */

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.UnhandledException;
import org.apache.commons.lang.WordUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.support.RequestContextUtils;

import ae.pcfc.etks.online.common.ConstantsCommon;
import ae.pcfc.etks.online.common.ConstantsCommon.WFProcessType;
import ae.pcfc.etks.online.common.delegate.AdminClientPersonReviewDelegate;
import ae.pcfc.etks.online.common.delegate.AppMetaDataDelegate;
import ae.pcfc.etks.online.common.delegate.ClientRegistrationDelegate;
import ae.pcfc.etks.online.common.delegate.UserReqDelegate;
import ae.pcfc.etks.online.common.util.CommonUtils;
import ae.pcfc.etks.online.common.vo.AdminApprovalVO;
import ae.pcfc.etks.online.common.vo.ClientPersonReqVO;
import ae.pcfc.etks.online.common.vo.ClientPersonVO;
import ae.pcfc.etks.online.common.vo.LabelVO;
import ae.pcfc.etks.online.common.vo.SCPersonVO;
import ae.pcfc.etks.online.common.vo.StepActionVO;
import ae.pcfc.etks.online.common.vo.StepCommentVO;
import ae.pcfc.etks.online.common.vo.UserVO;
import ae.pcfc.etks.online.web.ConstantsAdmin;
import ae.pcfc.etks.online.web.PageType;
import ae.pcfc.etks.online.web.ViewPath;
import ae.pcfc.etks.online.web.ViewUtils;
import ae.pcfc.etks.online.web.common.Constants;
import ae.pcfc.etks.online.web.controller.BaseController;
import ae.pcfc.etks.online.web.model.ClientPersonRegister;
import ae.pcfc.etks.online.web.model.RegisterAdminReview;
import ae.pcfc.etks.online.web.util.SecurityUtils;

@Controller
@RequestMapping(ViewPath.ADMIN_GENERAL_PERSON_REQUEST_CLIENT)
public class AdminClientPersonController extends BaseController{

	
	private AdminClientPersonReviewDelegate adminClientPersonReviewDelegate;

	@Resource(name = "adminClientPersonReviewDelegate")
	public void setAdminClientPersonReviewDelegate(AdminClientPersonReviewDelegate adminClientPersonReviewDelegate) {
		this.adminClientPersonReviewDelegate = adminClientPersonReviewDelegate;
	}

	private UserReqDelegate userReqDelegate;

	@Resource(name = "userReqDelegate")
	public void setUserReqDelegate(UserReqDelegate userReqDelegate) {
		this.userReqDelegate = userReqDelegate;
	}

	private AppMetaDataDelegate appMetaDataDelegate;

	@Resource(name = "appMetaDataDelegate")
	public void setAppMetaDataDelegate(AppMetaDataDelegate appMetaDataDelegate) {
		this.appMetaDataDelegate = appMetaDataDelegate;
	}

	private ClientRegistrationDelegate clientRegistrationDelegate;
	
	@Resource(name = "clientRegistrationDelegate")
	public void setClientRegistrationDelegate(
			ClientRegistrationDelegate clientRegistrationDelegate) {
		this.clientRegistrationDelegate = clientRegistrationDelegate;
	}
	
	/**
	 * A factory method for creating or loading an existing company.
	 * <p/>
	 * Note that this method is annotated with @ModelAttribute, which means it
	 * will be invoked before every request handling method in this class in
	 * order to pre-create the model object either by loading it or by creating
	 * it from scratch. this method will be invoked before resolving @ModelAttribute
	 * Method Parameter
	 * 
	 * @param id
	 *            an optional parameter specifying the id of the
	 *            NonClientPersonVO. If left unspecified a new ClientPersonVO is
	 *            created.
	 * 
	 * @return an instance of an ClientPersonRegister model object
	 */

	@ModelAttribute(value = ConstantsAdmin.CLIENT_PERSON_REGISTER_ADMIN_REVIEW_USER_DATA_REQUEST_MODEL_KEY)
	public ClientPersonRegister populateReferenceData(HttpServletRequest request,
			@RequestParam(value = "id", required = false) String id, @RequestParam(value = "appid", required = false) String appid, Model model) {

		if (appid != null) {
			ClientPersonReqVO clientPersonReqVO = this.userReqDelegate.loadClientPersonReqByApplicationId(SecurityUtils.decrypt(appid));

			// ClientPersonVO clientPersonVO =
			// adminClientPersonReviewDelegate.getClientPersonByApplicationId(new
			// Long(appid));
			if (clientPersonReqVO != null) {
				ClientPersonRegister clientPersonRegister = new ClientPersonRegister();
				getMapper().map(clientPersonReqVO, clientPersonRegister);
				/*
				 * ClientPersonRegister clientPersonRegister = new
				 * ClientPersonRegister();
				 * adminClientPersonReviewDelegate.getMapper
				 * ().map(clientPersonVO, clientPersonRegister); String
				 * strDocURL = clientPersonVO.getStrUploadDocument();
				 * 
				 * String strDocName =
				 * strDocURL.substring(strDocURL.lastIndexOf('\\')+1,
				 * strDocURL.length());
				 * clientPersonRegister.setStrUploadURL(clientPersonVO
				 * .getStrUploadDocument());
				 * clientPersonRegister.setStrUploadDocName(strDocName);
				 */
				String trakheesId = clientPersonReqVO.getStrTrakheesId();
				if(trakheesId == null){
				    throw new UnhandledException("Invalid trakhees Id no: "+ trakheesId, null);
				}
				SCPersonVO scPersonVO = this.clientRegistrationDelegate.findSCPersonByTrakheesId(trakheesId);
				
				if(scPersonVO == null ){			
					throw new UnhandledException("Invalid trakhees Id no: "+ trakheesId, null);
				} else{
				    model.addAttribute(ConstantsAdmin.CLIENT_PERSON_REGISTER_SUMMARY_REQUEST_MODEL_KEY, scPersonVO);
				}

				return clientPersonRegister;
			}
		}

		// TODO Here we'll place the logic to load the User Data through an Id
		return new ClientPersonRegister();
	}

	@ModelAttribute(value = ConstantsAdmin.ADMIN_ACTION_HISTORY_REQUEST_MODEL_KEY)
	public AdminApprovalVO populateActionHistory(HttpServletRequest request,
			@RequestParam(value = "appid", required = false) String appid) {

		if (appid != null) {
			AdminApprovalVO adminApprovalVO = appMetaDataDelegate.loadAppMetaData(SecurityUtils.decrypt(appid));			
			return (adminApprovalVO == null) ? new AdminApprovalVO() : adminApprovalVO;
		}

		// TODO Here we'll place the logic to load the User Data through an Id
		return new AdminApprovalVO();
	}

	@ModelAttribute(ConstantsAdmin.NON_CLIENT_PERSON_REGISTER_ACTION_TYPE_LIST_REQUEST_MODEL_KEY)
	public List<LabelVO> populateActionTypeListModel(Locale locale) {

		List<LabelVO> labelList = new ArrayList<LabelVO>();

		LabelVO labelVO = new LabelVO();
		labelVO.setId(ConstantsCommon.APPROVE);
	
		labelVO.setLabelAr(getMessageSource().getMessage("label.admin.approve", null, locale));
		labelVO.setLabelEn(getMessageSource().getMessage("label.admin.approve", null, locale));
		labelList.add(labelVO);

		labelVO = new LabelVO();
		labelVO.setId(ConstantsCommon.REJECT);
		labelVO.setLabelAr(getMessageSource().getMessage("label.admin.reject", null, locale));
		labelVO.setLabelEn(getMessageSource().getMessage("label.admin.reject", null, locale));
		labelList.add(labelVO);

		return labelList;
	}

	/*@RequestMapping(value = "/form.htm", method = RequestMethod.GET)
	public void form(@RequestParam(value = "appid", required = true) String appid,
			@RequestParam(value = "UserName", required = true) String userName,
			@RequestParam(value = "TaskID", required = true) String taskID,
			@RequestParam(value = "Incident", required = true) String incident,
			@RequestParam(value = "StepName", required = true) String stepName,
			@RequestParam(value = "StepCode", required = true) String stepCode,
			@ModelAttribute(value = ConstantsAdmin.REGISTER_ADMIN_REVIEW_REQUEST_MODEL_KEY) RegisterAdminReview adminReview) {

		adminReview.setStrApplicationId(appid);
		adminReview.setStrUserName(userName);
		adminReview.setStrTaskId(taskID);
		adminReview.setStrIncidentNo(incident);
		adminReview.setStrStepName(stepName);
		adminReview.setDepartment(UtilCommon.getDepartmentFromStepCode(stepCode));

	}*/
	@RequestMapping(value = "/form.htm", method = RequestMethod.GET)
	public void form(HttpServletRequest request,
		@RequestParam(value = "appid", required = true) String appid,
		@RequestParam(value = "Incident", required = true) String incident,
		@RequestParam(value = "StepName", required = true) String stepName,
		@ModelAttribute(value = ConstantsAdmin.REGISTER_ADMIN_REVIEW_REQUEST_MODEL_KEY) RegisterAdminReview adminReview) {
	    	adminReview.setStrApplicationId(appid);
		String userName = request.getRemoteUser();
		if(!StringUtils.isBlank(userName)){
			userName=WordUtils.capitalize(userName.toLowerCase(),new char[]{'.'});
			// TEMPORARY FIX - Code added to make sure user name is matching with one in Active directory(case sensitive)
		    final String DOT_SEPERATOR = "."; 
		    final String MIDDLE_NAME = "Al";
		    if(StringUtils.startsWith(StringUtils.substringAfter(userName,DOT_SEPERATOR), MIDDLE_NAME))		    		
		    {
		    	String tempLastName = StringUtils.substringAfter(userName,DOT_SEPERATOR);	
		    	tempLastName = MIDDLE_NAME+WordUtils.capitalize(StringUtils.substringAfter(tempLastName,MIDDLE_NAME));
		    	userName = StringUtils.substringBefore(userName,DOT_SEPERATOR)+DOT_SEPERATOR+tempLastName;
		    }
		    // End TEMP FIX
		    adminReview.setStrUserName(CommonUtils.appendDomainPrefix(userName));		 
		}
		adminReview.setStrIncidentNo(SecurityUtils.decrypt(incident));
		stepName = SecurityUtils.decrypt(stepName);
		adminReview.setStrStepName(stepName);
		// delete 'REVIEW' from 'CED Review' and trim 
		//adminReview.setDepartment(StringUtils.trim(StringUtils.remove(stepName.toUpperCase(), ConstantsCommon.PROCESS_STEP_REVIEW).toUpperCase()));
	}
	@RequestMapping(value = "/show.htm", method = RequestMethod.GET)
	public void show(@RequestParam(value = "appid", required = true) String appid) {
	}

	/**
	 * Custom handler for displaying the form, i.e.: GET requests for
	 * /admin/general/person/request/client.
	 * <p/>
	 * Note that this handler returns void instead of a {@link ModelAndView},
	 * signifying a default logical view name should be selected by Spring MVC.
	 * The ui {@link Model} is supplied as a parameter to the method and
	 * populated with the new company registration object to be rendered.
	 * 
	 * @see #form(HttpServletRequest,SessionStatus,RegisterAdminReview,
	 *      BindingResult)
	 * @see WEB-INF/jsp/admin/general/person/request/client/form.jsp
	 */

	@RequestMapping(method = RequestMethod.POST, value = "/form.htm")
	public String form(HttpServletRequest request, HttpSession session, SessionStatus status,
			@ModelAttribute(value = ConstantsAdmin.REGISTER_ADMIN_REVIEW_REQUEST_MODEL_KEY) @Valid RegisterAdminReview adminReview,
			BindingResult errors) {

		AdminApprovalVO adminVO = new AdminApprovalVO();

		getMapper().map(adminReview, adminVO);
		//adminVO.setStrProcessCode(ConstantsAdmin.PROCESS_CODE_CLIENT_PERSON_REGISTRATION);
		adminVO.setProcessCode(WFProcessType.CLIENT_PERSON_REGISTRATION);
		//adminVO.setStrProcessStep(adminReview.getStrStepName());
        /*if(adminReview != null && adminReview.getDepartment() != null){
			adminVO.setDepartment(adminReview.getDepartment());
        	adminVO.setStrProcessStep(ConstantsAdmin.PROCESS_STEP_REVIEW_CLIENT_PERSON + ConstantsCommon.PROCESS_STEP_CODE_CONNECTOR + adminReview.getDepartment());
        }else{
        	adminVO.setStrProcessStep(ConstantsAdmin.PROCESS_STEP_REVIEW_CLIENT_PERSON);
        }*/

        	adminVO.setStrApplicationId(SecurityUtils.decrypt(adminReview.getStrApplicationId()));
		adminVO.setActionDate(Calendar.getInstance().getTime());

		StepActionVO stepActionVO = new StepActionVO();
		getMapper().map(adminReview, stepActionVO);
		stepActionVO.setActionDate(Calendar.getInstance().getTime());

		StepCommentVO stepCommentVO = new StepCommentVO();
		getMapper().map(adminReview, stepCommentVO);
		stepCommentVO.setCommentDate(Calendar.getInstance().getTime());

		adminVO.setCommentsVOs(new ArrayList<StepCommentVO>(Arrays.asList(stepCommentVO)));
		adminVO.setStepActionVOs(new ArrayList<StepActionVO>(Arrays.asList(stepActionVO)));

		ClientPersonReqVO clientPersonReqVO = this.userReqDelegate.loadClientPersonReqByApplicationId(adminVO.getStrApplicationId());

		UserVO userVO = new UserVO();
		getMapper().map(clientPersonReqVO, userVO);
		userVO.setCreateDate(Calendar.getInstance().getTime());
		userVO.setStrType(Constants.USER);

		ClientPersonVO clientPersonVO = new ClientPersonVO();
		getMapper().map(clientPersonReqVO, clientPersonVO);

		clientPersonVO.setUserVOs(new ArrayList<UserVO>(Arrays.asList(userVO)));
		clientPersonVO.setCreateDate(Calendar.getInstance().getTime());
		clientPersonVO.setStrClientType(Constants.PERSON);
		clientPersonVO.setStrStatus(Constants.ACTIVE);

		if(adminVO.getStrActionType().equals(ConstantsCommon.APPROVE)){
			adminVO.setStrStatusEn(this.getMessageSource().getMessage("msg.workflow.status.approved", null, Locale.ENGLISH));
			adminVO.setStrStatusAr(this.getMessageSource().getMessage("msg.workflow.status.approved", null, new Locale(Constants.LOCALE_ARABIC)));
		}else if(adminVO.getStrActionType().equals(ConstantsCommon.REJECT)){
			adminVO.setStrStatusEn(this.getMessageSource().getMessage("msg.workflow.status.rejected", null, Locale.ENGLISH));
			adminVO.setStrStatusAr(this.getMessageSource().getMessage("msg.workflow.status.rejected", null, new Locale(Constants.LOCALE_ARABIC)));
		}
		
		adminVO.setStrInProgressStatusEn(this.getMessageSource().getMessage("msg.workflow.status.in.progress", null, Locale.ENGLISH));
		adminVO.setStrInProgressStatusAr(this.getMessageSource().getMessage("msg.workflow.status.in.progress", null, new Locale(Constants.LOCALE_ARABIC)));
		
		adminClientPersonReviewDelegate.reviewRegisterClientPerson(adminVO, clientPersonVO);

		if (errors.hasErrors()) {
			return ViewUtils.DEFAULT_VIEW;
		}

		status.setComplete();
		session.setAttribute(ConstantsAdmin.SUCCESS_PARAM,
				getMessageSource().getMessage("success.user.info.edit", null, RequestContextUtils.getLocale(request)));

		/*
		 * if( adminVO != null) {
		 * adminClientPersonReviewDelegate.getMapper().map
		 * (nonClientPersonRegisterAdminReview, adminVO);
		 * adminVO.setStrApplicationId(new Long(request.getParameter("appid")));
		 * adminVO.setActionDate(new Date());
		 * 
		 * adminClientPersonReviewDelegate.reviewRegisterClientPerson(adminVO);
		 * status.setComplete(); request.setAttribute("success",
		 * getMessageSource().getMessage("label.success.registerservice",
		 * null,RequestContextUtils.getLocale(request)));
		 * 
		 * }
		 */

		return ViewUtils.getRedirect(ViewPath.USER_INTERNAL_TRAKHEES_STAFF_INBOX, PageType.LIST);

	}
}
